<?php

namespace addons\knowbase\controller;

use addons\knowbase\library\Page;
use app\common\model\knowbase\Project;
use app\common\model\knowbase\ProjectPage;
use think\addons\Controller;
use think\Config;
use think\Db;

class Index extends Controller
{
    protected function _initialize()
    {
        parent::_initialize();
        if (request()->isGet()) {
            $this->assign('controller', $this->controller);
            $this->assign('action', $this->action);
            $config       = get_addon_config('knowbase');
            $site         = Config::get("site");
            $friends_link = array_filter(array_map(function ($v) {
                $v = explode("|", $v);
                if (isset($v[1])) {
                    return [
                        'name'   => $v[0] ?? '',
                        'url'    => $v[1] ?? '',
                        'target' => isset($v[2]) && $v[2] == 'blank' ? 'blank' : '_self',
                    ];
                } else {
                    return '';
                }
            }, array_filter(explode("\r\n", $config['friends_link']))));
            $loading      = '';
            if ($config['image_lazy_load']) {
                $loading = '/assets/addons/knowbase/imgs/loading.png';
                $file    = ROOT_PATH . 'public' . DS . '/assets/addons/knowbase/imgs/loading.gif';
                if (is_file($file)) {
                    $loading = '/assets/addons/knowbase/imgs/loading.gif';
                }
            }

            $url_list = knowbase_handle_url_protocol(addon_url('knowbase/index/projects'));
            $url_home = '/';
            if ($config['jump_link_type'] == 2 && $config['jump_link']) {
                $url_home = $config['jump_link'];
            } else if ($config['jump_link_type'] == 1) {
                $url_home = $url_list;
            }

            if (isset($config['table_over_show']) && $config['table_over_show']) {
                $table_over_show = 1;
            } else {
                $table_over_show = 0;
            }

            if (isset($config['show_document_time']) && $config['show_document_time']) {
                $show_document_time = 1;
            } else {
                $show_document_time = 0;
            }
            $ads = [];
            if ($config['show_ads']) {
                $ads = array_filter(array_map(function ($v) {
                    $v = explode("|", $v);
                    if (isset($v[1])) {
                        $vv = explode(":", $v[1],2);
                        if (strpos($v[1], 'qq:')!==false){
                            $url ="tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin={$vv[1]}";
                        } else {
                            $url = $vv[1];
                        }
                        return [
                            'name'   => $v[0],
                            'url'    => $url,
                            'target' => isset($v[2]) && $v[2] == 'blank' ? 'blank' : '_self',
                        ];
                    } else {
                        return '';
                    }
                }, array_filter(explode("\r\n", $config['ads_link']))));
            }
            $this->assign('tongji', $config['open_baidu_tongji'] && $config['baidu_tongji']?1:0);
            $this->assign('tongji_url', $config['open_baidu_tongji'] && $config['baidu_tongji']?$config['baidu_tongji']:'');
            $this->assign('ads', $ads);
            $this->assign('show_document_time', $show_document_time);
            $this->assign('table_over_show', $table_over_show);
            $this->assign('url_list', $url_list);
            $this->assign('url_home', $url_home);
            $this->assign('friends_link', $friends_link);
            $this->assign('show_copyright', $config['show_copyright']);
            $this->assign('copyright', $config['copyright']);
            $this->assign('content_theme', $config['content_theme']);
            $this->assign('code_theme', $config['code_theme']);
            $this->assign('code_show_number', $config['code_show_number']);
            $this->assign('loading', $loading);
            $this->assign('static_cdn_type', $config['static_cdn_type']);
            $this->assign('nav_left_style', $config['nav_left_style']);
            if ($site && isset($site['beian']) && $site['beian']) {
                $config['beian'] = $site['beian'];
            }
           
            $this->assign('header_nav_type', $config['header_nav_type']);
            if ($config['header_nav_type']==1) {
                $navs = [];
                $nav_links = array_filter(array_map(function ($v) {
                    $v = explode("|", $v);
                    if (isset($v[1])) {
                        $vv = explode(":", $v[1],2);
                        if (strpos($v[1], 'qq:')!==false){
                            $url ="tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin={$vv[1]}";
                        } else {
                            $url = $v[1];
                        }
                        return [
                            'name'   => $v[0],
                            'url'    => $url,
                            'target' => isset($v[2]) && $v[2] == 'blank' ? 'blank' : '_self',
                        ];
                    } else {
                        return '';
                    }
                    
                }, array_filter(explode("\r\n", $config['header_nav_link']))));
                foreach ($nav_links as $v){
                    if (strpos($v['name'], '@')!==false){
                        $vv = explode("@", $v['name']);
                        $v['name'] = $vv[1];
                        $navs[$vv[0]]['sons'][] = $v;
                    } else {
                        $navs[$v['name']] = $v;
                    }
                }
                $this->assign('navs', $navs);
            }
            $wa_beian_number = '';
            if ($config['wa_beian']) {
                if (preg_match("/\d+/i", $config['wa_beian'], $match)){
                    $wa_beian_number = $match[0];
                }
            }
            $this->assign('beian', $config['beian']);
            $this->assign('wa_beian', $config['wa_beian']);
            $this->assign('wa_beian_number', $wa_beian_number);
            $this->assign('version', config('knowbase_ini.version'));
        }

    }

    /**
     * 插件配置远程校验
     * @return array
     */
    public function check()
    {
       
        $param = input('param', '');
        [$type, $field] = explode('.', $param);
       
        $value = input('row.' . $field, '');
        switch ($type) {
            case 'url':
                if (filter_var($value, FILTER_VALIDATE_URL) === false) {
                    return ["code" => 0, "msg" => 'URL地址格式不正确'];
                } else {
                    return ["code" => 1, "msg" => 'ok'];
                }
            case 'inner_url':
                if ($value && url_clean($value)!=$value){
                    return ["code" => 0, "msg" => 'URL地址配置不正确'];
                } else {
                    return ["code" => 1, "msg" => 'ok'];
                }
            default:
                return ["code" => 0, "msg" => 'unknown'];
        }

    }

    public function index()
    {
        $config = get_addon_config('knowbase');
        if ($config['open_home_sitemap']) {
            $data = \app\common\model\knowbase\Project::getHotPages();
            $data = knowbase_groupsbyid($data,'knowbase_project_id');
            $this->assign('header_title', $config['sitemap_title']);
            $this->assign('header_keywords', $config['sitemap_keywords']);
            $this->assign('header_description', $config['sitemap_description']);
            $this->assign('data', $data);
            return $this->view->fetch();
        } else {
            header('Location:/projects.html');
            exit;
        }
    }

    /**
     * 项目列表
     */
    public function projects()
    {
       
        $config = get_addon_config('knowbase');
        if (isset($config['only_one_project']) && $config['only_one_project']) {
            $show_project_id = intval($config['show_project_id']);
            if ($show_project_id > 0 && $project = \app\common\model\knowbase\Project::where('status', 1)->where('id', $show_project_id)->find()) {
                header("Location:" . addon_url("knowbase/index/project", [':id' => $project['id']]));
                exit;
            }
            $project = \app\common\model\knowbase\Project::where('status', 1)->order('weigh desc')->find();
            if ($project) {
                header("Location:" . addon_url("knowbase/index/project", [':id' => $project['id']]));
                exit;
            } else {
                $this->error('未配置知识库，请先配置');
            }
        }
        $model = new \app\common\model\knowbase\Project;
       
        $model
            ->where('status', 1);
        $search = request()->param('search', '', 'urldecode,trim');
        $params = ['page' => request()->param('p')];
        if ($search) {
            $model->whereLike('title', '%' . $search . '%');
            $params['search'] = $search;
        }
        $list = $model->order('weigh', 'desc')
            ->paginate(12, false, $params);

        if (request()->isAjax()) {
            foreach ($list as $v) {
               
            }
            $result = ['total' => $list->total(), 'rows' => $list->items()];
            return json($result);
        }
        $Page = new Page($list->total());
       
        $show = $Page->show();
        $rows = collection($list->items())->toArray();
        
       
        $this->assign('web_title_type', 0);
        $this->assign('multipage', $show);
        $this->assign('search', $search);
        $this->assign('header_title', $config['project_title']);
        $this->assign('header_keywords', $config['project_keywords']);
        $this->assign('header_description', $config['project_description']);
        $this->assign('project_type', $config['project_type']);
        if ($config['project_type']) {
           
            if ($rows) {
                $ids = implode(",", array_column($rows, 'id'));
                $table_project = Db::getTable('knowbase_project');
                $table_page = Db::getTable('knowbase_project_page');
               
                $openPageIds = implode(",", array_column(Db::query("SELECT id FROM {$table_page} where knowbase_project_id in (".$ids.") and status_switch=1 and deletetime IS NULL"),'id'));
                if (!$openPageIds) {
                    $openPageIds = "0";
                }
                $pages = Db::query("SELECT 
                        c.id,
                        c.title,
                        p.page_id,
                        p.page_title,
                        p.identify,
                        row_number,
                        type
                        FROM 
                            {$table_project} c
                        LEFT JOIN (
                            SELECT 
                                knowbase_project_id,
                                id as page_id,
                                title as page_title,
                                identify,
                                @row_number := IF(@current_category = knowbase_project_id, @row_number + 1, 1) AS row_number,
                                @current_category := knowbase_project_id,
                                        type
                            FROM 
                                (SELECT @row_number := 0, @current_category := NULL) AS vars,
                                {$table_page}
                                        where status_switch=1 and deletetime IS NULL and id in ({$openPageIds})
                            ORDER BY 
                                knowbase_project_id, type desc, weigh desc
                        ) p ON c.id = p.knowbase_project_id
                        WHERE 
                            c.id in ({$ids}) and 
                             p.row_number <= 10;
                ");
               
                $urls = array_filter($pages,function ($v){
                    return $v['type']=='url';
                });
                $contents = [];
                if ($urls) {
                    $contents = knowbase_groupbyid(collection(ProjectPage::whereIn('id',array_column($urls,'page_id'))->field('id,content')->select()));
                }
                $page_list = knowbase_groupsbyid($pages,'id');
                foreach ($rows as &$v) {
                    $v['items'] = [];
                    foreach ($page_list[$v['id']]??[] as $vv) {
                        $page = [
                            'id' =>$vv['page_id'],
                            'title' =>$vv['page_title'],
                            'identify' =>$vv['identify'],
                            'type' =>$vv['type'],
                        ];
                        $page['url'] = $vv['type']=='url'?$contents[$vv['page_id']]['content']:knowbase_page_addon_url($v,$page);
                        $v['items'][] = $page;
                    }
                    unset($v);
                }
            }
            $this->assign('rows', $rows);
            return $this->view->fetch('projects_with_list');
        } else {
            foreach ($rows as &$v) {
                if($v['image']) {
                    $v['image'] = cdnurl($v['image']);
                }
                unset($v);
            }
            $this->assign('rows', $rows);
            return $this->view->fetch();
        }
    }

    /**
     * 项目
     */
    public function project()
    {
        $project_id = request()->param('id', 0, 'intval');
        $project    = Project::where('id', $project_id)->where('status', 1)->find();
        if (!$project) {
            $this->error('请求操作有误');
        }

        $list = [];
        ProjectPage::getList($project, 0, $list);
        if (!$list) {
            $this->error('项目文档为空');
        }
       
       
        header("Location:" . knowbase_page_addon_url($project,$list[0]));
        exit;
    }

    /**
     * 查看某个项目的文档
     */
    public function document()
    {
        $project_id = request()->param('project_id', 0, 'intval');
        if ($id = request()->param('id', 0, 'intval')) {
            $item = ProjectPage::where('id', $id)->where('status_switch', 1)->find();
            if (!$item) {
                $this->error('请求操作有误');
            }
            $project_id = $item['knowbase_project_id'];
        }

        if (!$project_id) {
            $this->error('请求操作有误');
        }

        $project = Project::where('id', $project_id)->where('status', 1)->find();
        if (!$project) {
            $this->error('请求操作有误');
        }

       
        if (!$id && !$item = ProjectPage::where('knowbase_project_id', $project_id)->where('status_switch', 1)->order('type asc,weigh desc')->find()) {
            $this->error('请求操作有误');
        }
        $project->where('id', $project['id'])->inc('views')->update();
        $this->handleDocument($project,$item);
        return $this->view->fetch();
    }

   
    public function rewrite_document(){
        $project_identify = request()->param('name', '');
        $page_identify = request()->param('id', '');
        if (!$project_identify || !$page_identify) {
            $this->error('请求操作有误');
        }
        $project = Project::where('identify', $project_identify)->where('status', 1)->find();
        if (!$project) {
            $this->error('请求操作有误');
        }

        if (is_numeric($page_identify)) {
             $item = ProjectPage::where('knowbase_project_id', $project['id'])->where('id',$page_identify)->where('status_switch', 1)->find();
        } else {
             $item = ProjectPage::where('knowbase_project_id', $project['id'])->where('identify',$page_identify)->where('status_switch', 1)->find();
        }

        if (!$item) {
            $this->error('请求操作有误');
        }

        $project->where('id', $project['id'])->inc('views')->update();
        $this->handleDocument($project, $item);
        return $this->view->fetch('document');
    }
    /**
     * 检查密码
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function checkPassword()
    {
        $project_id    = request()->param('project_id', 0, 'intval');
        $id            = request()->param('id', 0, 'intval');
        $password      = request()->param('password', '');
        $project       = Project::where('id', $project_id)->where('status', 1)->find();
        $item          = ProjectPage::where('id', $id)->where('knowbase_project_id', $project_id)->where('status_switch', 1)->find();
        $rightPassword = ProjectPage::checkPassword($project, $item, $password);
        if ($rightPassword) {
            $this->success('ok');
        } else {
            $this->error('密码错误');
        }
    }

    /**
     * 查找页面
     * @return void
     */
    public function checkPage()
    {
        $project_id = request()->param('project_id', 0, 'intval');
        $search     = request()->param('search', '', 'strip_tags,trim');
        
        $closeDirsPids = knowbase_get_cache('checkPage_closeDirs_'.$project_id,function () use ($project_id) {
            $closeDirs = collection(ProjectPage::where('type','dir')
                ->where('knowbase_project_id',$project_id)
                ->where('status_switch',0)
                ->field('id')
                ->select())
                ->toArray();

            $closeDirsPids = [];
            foreach ($closeDirs as $v) {
                $closeDirsPids[] = $v['id'];
                $closeDirsPids = array_merge($closeDirsPids, ProjectPage::getAllNodes($v['id']));
            }
            $closeDirsPids = array_values(array_unique($closeDirsPids));
            return $closeDirsPids;
        });
        
        $list       = ProjectPage::where('knowbase_project_id', $project_id)
            ->field('id,pid,title,content,type,updatetime')
            ->where('status_switch', 1)
            ->where(function ($q) use ($search) {
                return $q->where('title', 'like', "%{$search}%")
                    ->whereOr('content', 'like', "%{$search}%");
            })
            ->order('updatetime', 'desc')
            ->limit(100)
            ->select();
        $list = array_filter($list,function ($v) use ($closeDirsPids) {
            return $v['pid']==0 || !in_array($v['pid'],$closeDirsPids);
        });
       
        if (!$list) {
            $this->success('没有找到相应的结果', '', []);
        }
        $list = collection($list)->toArray();
        
        $titles = knowbase_groupbyid(collection(ProjectPage::where('knowbase_project_id', $project_id)
            ->field('id,pid,title')
            ->where('status_switch', 1)
            ->select())->toArray());
        foreach ($list as &$v) {
            foreach ($v as $k => $vv) {
                if (strpos($k, '_text') !== false) {
                    unset($v[$k]);
                }
            }
            $url = $v['type']=='url'?$v['content']:'';
            $v['content'] = knowbase_extract_substring($v['content'], $search);
           
            $v['content'] = preg_replace("/```[\w\W]+?```/m", '', $v['content']);
            $v['content'] = preg_replace("/\|[\w\W]+?\|/m", '', $v['content']);
            $v['content'] = preg_replace("/\[([\w\W]+?)\]/m", '$1', $v['content']);
            $v['content'] = preg_replace("/\([\w\W]+?\)/m", '', $v['content']);
            $v['content'] = preg_replace("/\([\w\W]?\)/m", '', $v['content']);
            $v['content'] = preg_replace("/`[\w\W]+?`/m", '', $v['content']);
            $v['content'] = preg_replace("/`[\w\W]?`/m", '', $v['content']);
            $v['content'] = preg_replace("/\\$[\w\W]+?\\$/m", '', $v['content']);
            $v['content'] = preg_replace("/\\$[\w\W]?\\$/m", '', $v['content']);
            $v['content'] = trim(strip_tags(str_replace(["#", "\r", "\n", '-', "`"], '', $v['content'])));

            $v['title']   = str_replace($search, "<span style='color:red;'>{$search}</span>", $v['title']);
            $v['content'] = str_replace($search, "<span style='color:red;'>{$search}</span>", $v['content']);
            $v['date']    = date('Y-m-d H:i', $v['updatetime']);
            $pid          = $v['pid'];
            $ts           = [];
            while ($pid > 0) {
                $ts[] = $titles[$pid]['title'];
                $pid  = $titles[$pid]['pid'];
            }
            $ts[]        = '首页';
            $ts          = array_reverse($ts);
            $v['belong'] = '<span class="label label-primary">' . implode('<i class="fa fa-angle-right"></i>', $ts) . '</span>';
            if ($url) {
                $v['url'] = $v['content'] = $url;
            } else {
                $v['url'] = '';
            }
            unset($v['updatetime']);
            unset($v);
        }
        $this->success('ok', '', $list);
    }

    protected function handleDocument($project,$item) {
        $id = $item['id'];
        if (request()->isAjax()) {
            if ($id <= 0) {
                $this->error('丢失请求参数');
            } else if (!$item = ProjectPage::where('knowbase_project_id', $project['id'])->where('id', $id)->where('status_switch', 1)->find()) {
                $this->error('请求操作有误');
            }
            $rightPassword = ProjectPage::checkPassword($project, $item);
            if (!$rightPassword) {
                $this->error('请输入密码', '', ['code' => 100]);
            } else if (!$rightGroup = ProjectPage::checkUserGroup($project, $item, $allowGroups)) {
                if (\app\common\library\Auth::instance()->id) {
                    $this->error('无权查看该页面', '', ['code' => 101]);
                } else {
                    $this->error('无权查看该页面，请先登录!', knowbase_diy_login_url()?:parse_url(knowbase_page_addon_url($project,$item))['path'], ['code' => 102]);
                }
            }
           
            $item->where('id', $item['id'])->inc('views')->update();
            $item->visible(['id', 'title', 'content', 'updatetime', 'views']);
            $item               = $item->toArray();
            $item['updatetime'] = date('Y-m-d H:i', $item['updatetime']);
            knowbase_format_markdown($item['content']);
            unset($item['access_type_text']);
            unset($item['type_text']);
            $this->success('ok', null, $item);
        } else {
           
            $list = [];
            $menu = ProjectPage::getList($project, $id, $list);
            if ($id <= 0) {
                $id = $list[0]['id'];
            }
            if (!$item = ProjectPage::where('knowbase_project_id', $project['id'])->where('id', $id)->where('status_switch', 1)->find()) {
                $this->error('请求操作有误');
            }
            $item->where('id', $item['id'])->inc('views')->update();
            $rightPassword = ProjectPage::checkPassword($project, $item);
            if ($rightPassword) {
                $rightGroup = ProjectPage::checkUserGroup($project, $item, $allowGroups);
                if (!$rightGroup) {
                    if (\app\common\library\Auth::instance()->id) {
                        $this->error('无权查看该页面');
                    } else {
                        $this->error('无权查看该页面，请先登录!', '/index/user/login.html');
                    }
                }
            }
            
            if ($item['type']=='url'){
                header("Location: {$item['content']}");
                exit;
            }
        }


        $this->assign('project_id', $project['id']);
        $this->assign('project', $project);
        $this->assign('page_id', $item['id']);
        $this->assign('menu', $menu);
        $this->assign('rightPassword', (int)$rightPassword);
        $this->assign('header_title', $item['title']);
        $this->assign('header_keywords', ProjectPage::getKeywords($item));
        $this->assign('header_description', ProjectPage::getDescription($item));
        $content = $item['content'];
        if (!$rightPassword) {
            $content = '';
        } else {
            knowbase_format_markdown($content);
        }

        $config       = get_addon_config('knowbase');
        if (isset($config['web_title_type']) && $config['web_title_type'] == 1) {
            $site         = Config::get("site");
            $site['name'] = $project['title'];
            $this->assign('site',$site);
        }
        $this->assign('web_title_type',isset($config['web_title_type']) ? $config['web_title_type'] : 0);
        $this->assign('item', $item);
        $this->assign('content', $content);
       
        $this->assign('style', cookie('style') ?? 'morning');
       
        $this->assign('url_check_page', knowbase_handle_url_protocol(addon_url('knowbase/index/checkPage')));
        $this->assign('url_check_password', knowbase_handle_url_protocol(addon_url('knowbase/index/checkPassword')));
    }

}

